package com.fruitstore.jdbc1.dao;

import com.bookstore.utils.DruidUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDao<T> {
    private Class<T> clazz;
    Type type;

    public BaseDao() {
        Type type = getClass().getGenericSuperclass();
        ParameterizedType parameterizedType = (ParameterizedType) type;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        clazz = (Class<T>) actualTypeArguments[0];
    }
    public <T> T query(String sql, Object...params) {
        try {
            Connection conn = DruidUtils.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            while (rs.next()) {
                T t = (T) clazz.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rsmd.getColumnName(i + 1);
                    Object object = rs.getObject(i + 1);
                    setValue(clazz, columnName, object);
                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
       return null;
    }

    public List<T> queryList(String sql,Object...params){
        List<T> list=new ArrayList<T>();
        try {
            Connection conn = DruidUtils.getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            while (rs.next()){
                T t1 = clazz.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rsmd.getColumnName(i + 1);
                    Object object = rs.getObject(i + 1);
                    setValue(t1,columnName,object);
                }
                list.add(t1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;

    }

    //通过反射技术给obj对象的property属性赋propertyValue值
    private void setValue(Object obj, String propertyName, Object propertyValue) {
        Class clazz = obj.getClass();
        try {
            //获取propertyName字符串应对的属性名，例如：“fid”去找obj对象的fid属性
            Field field = clazz.getDeclaredField(propertyName);
            if(field!=null){
                field.setAccessible(true);
                field.set(obj, propertyValue);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
